---@class LBSManager
LBSManager = {
    myChatChannel = {},
    ---@type LBSRoom
    curRoom = nil,
    ---@type LBSRoom
    preRoom = nil,
    ---@type LBSRoom[][]
    roomList = {{},{}},
    enableLBS = true,
    joinState = 0,
    isSelectLBS = false,
    joinTime = 0,
    roomState = 0
}
local this = LBSManager
local ROOM_MAX_COUNT = 20
local ROOM_CHANGE_TIME = 5 --主城/附近切换时间
local orderId = 1
local cityMsg = {}
local joinData = {}
local saved = false
function LBSManager.EnableLBS()
    return this.enableLBS
end
function LBSManager.SetEnableLBS(enable)
    this.enableLBS = enable
end
function LBSManager.GetLocationName()
    local debugLbs =  GetPlayerPrefs("DebugLbsLocation")
    if not string.IsNilOrEmpty(debugLbs) then
        logError("使用debug定位:"..debugLbs)
        return debugLbs
    end
    local name = LBSLocation.GetLocationDataGPS()
    if string.IsNilOrEmpty(name) then
        name = Util.GetPlayerPrefs("LocationGPS")
    end
    if name == nil or name == "" then
        name = "上海市"
    end
    if not saved then
        Util.SetPlayerPrefs("LocationGPS",name)
        saved = true
    end

    return name
end
function LBSManager.GetWorldRooms()
    return this.roomList[1]
end
function LBSManager.GetLBSRooms()
    return this.roomList[2]
end


function LBSManager.JoinRoom(isLBS)
    if this.joinState == EnumConst.LBSJoinState.none then
        this.joinTime = 0
    end
    if isLBS then
        UISysTips.AddMsg(getLanguage("lbs_func_not_open"))
        return false
    end
    if HelperFunc.GetServerTime() - this.joinTime < ROOM_CHANGE_TIME or this.roomState ~= 0 then
        UISysTips.AddMsg(getLanguage("lbs_change_room_tip"))
        return false
    end
    if isLBS == this.isSelectLBS then
        return false
    end
    if isLBS and string.IsNilOrEmpty(this.GetLocationName()) then
        UISysTips.AddMsg(getLanguage("lbs_cannot_get_location"))
        return false
    end
    this.joinState = EnumConst.LBSJoinState.none
    this.joinTime = HelperFunc.GetServerTime()
    this.isSelectLBS = isLBS
    this.AutoJoinRoom()
    return true
end
function LBSManager.ChangeRoom(room,showTip)
    if this.roomState ~= 0 then
        if showTip then
            UISysTips.AddMsg(getLanguage("lbs_change_room_tip"))
        end
        return
    end
    utimer.remove(this.timerId)
    this.timerId = utimer.timeCall(LBSManager.DelayCheckJoinRoom,2000,-1)
    --this.QuitBroadcastChannel(this.curRoom)
    --this.joinBroadcastChannel(room)
    --this.JoinWorldFinished()
    if this.curRoom then
        this.roomState = 1
        this.QuitBroadcastChannel(this.curRoom)
        this.curRoom = room
    else
        this.roomState = 2
        this.joinBroadcastChannel(room)
    end
    FireEvent(Config.EventType.ChangeRoom)
end
function LBSManager.AutoJoinRoom()
    --[[if IsWindowEditor() then
        if this.isSelectLBS then
            if string.IsNilOrEmpty(this.GetLocationName()) then
                this.isSelectLBS = false
                this.JoinWorld()
            else
                this.JoinLBS()
            end
        else
            this.JoinWorld()
        end
    end]]
end
function LBSManager.DelayCheckJoinRoom()
    if this.roomState == 1 then
        this.QuitBroadcastChannel(this.preRoom)
    elseif this.roomState == 2 then
        this.joinBroadcastChannel(this.curRoom)
    end
end
--进入战斗后，再次进入主城，需要有一个触发获取城内其他人的事件
function LBSManager.LeaveRoom()
    this.joinState = EnumConst.LBSJoinState.none
    this.QuitBroadcastChannel(this.curRoom)
    this.curRoom = nil
end
---@private
function LBSManager.JoinWorld()
    if(not logicMgr.FuncOpenManager.isOpen(Config.FuncOpenType.City)) then
        return
    end
    if this.joinState ~= EnumConst.LBSJoinState.none then
        return
    end
    this.joinState = EnumConst.LBSJoinState.worldStart
    this.GetRooms(this.JoinRandomRoom)
end
---@private
function LBSManager.JoinLBS()
    if(not logicMgr.FuncOpenManager.isOpen(Config.FuncOpenType.City)) then
        return
    end
    if this.joinState ~= EnumConst.LBSJoinState.none then
        return
    end
    this.joinState = EnumConst.LBSJoinState.LBSStart
    this.GetRooms(this.JoinRandomRoom)
end
---@private
function LBSManager.JoinRandomRoom()
    ---@type LBSRoom[]
    local rooms
    local name
    local room
    local code = 1
    if this.joinState == EnumConst.LBSJoinState.worldStart then
        this.joinState = EnumConst.LBSJoinState.world
        rooms = this.GetWorldRooms()
        room = rooms[1]
        name = "room"
    else
        name = this.GetLocationName()
        this.joinState = EnumConst.LBSJoinState.LBS
        rooms = this.GetLBSRooms()
        for k,v in pairs(rooms) do
            if v.num < ROOM_MAX_COUNT then
                room = v
                break
            end
            code = math.max(code,v.code)
        end
    end
    if not room then
        room = this.AddRoom(name,1,code)
    end
    this.ChangeRoom(room,false)
end
---@private
function LBSManager.JoinWorldFinished()
    if this.curRoom == nil then
        --logError("没有加入房间")
        return
    end
    this.SendBroadCast()
end
function LBSManager.SendBroadCast(extraInfoTb)
    if this.curRoom == nil then
        --logError("pc聊天已屏蔽")
        return
    end
    local msg = {};
    local channelStr = this.curRoom.channel
    msg.Channel = channelStr;
    msg.Message = "c-i^t-y";
    msg.head = logicMgr.HeroManager.GetRoleHeadID()--logicMgr.HeroManager.getMyself().partnerModelId;
    msg.prof = -1--用不到的属性临时赋值HeroManager.getMyself().partnerModelId;
    msg.race = -1--用不到的属性临时赋值HeroManager.getMyself().partnerModelId;
    msg.roleId = logicMgr.HeroManager.GetRoleInfo().playerId;
    msg.roleName = logicMgr.HeroManager.GetRoleInfo().name;
    local _petInfo = PetManager.GetFollowPetInfo()
    local _genes = {}
    if _petInfo then
        _genes = _petInfo.genes
    end
    msg.genes =  _genes
    if extraInfoTb then
        for k,v in pairs(extraInfoTb) do
            msg[k] = v
        end
    end
    this.broadCastCityMsg(channelStr, msg);
end
function LBSManager.GetCurRoom()
    return this.curRoom
end
function LBSManager.GetCurRoomChannel()
    if this.curRoom then
        return this.curRoom.channel
    end
    return this.GetRoomChannel("room",1)
end
---@private
function LBSManager.AddRoom(name,num,code)
    ---@class LBSRoom
    local room= {}
    room.channel = this.GetRoomChannel(name,code)
    room.name = name
    room.code = code
    room.num = num
    room.isWorld = string.Contains(name,"room")
    if room.isWorld then
        table.insert(this.roomList[1],room)
    else
        local location = this.GetLocationName()
        if string.IsNilOrEmpty(location) then
            return
        end
        if name == location then
            table.insert(this.roomList[2],room)
        end
    end
    return room
end
---获取房间
---@private
function LBSManager.GetRooms(funcBack)
    local param = {channel = "world-room-"..AppConst.ServerId};
    local sendJosn=getJsonStr(param)
    local tempChanelWeb=string.gsub(logicMgr.LoginManager.GetHttpServerUrl(),"8080","8088")

    table.clear(this.roomList[1])
    table.clear(this.roomList[2])
    --logError("[LBSManager]GetRooms")
    WebMsgMgr:SendHttpRequest(tempChanelWeb.."chat/channels",sendJosn,function (msg)
        --logError("[GetRooms] msg : "..msg)
        local v = decodeJsonStrToTabel(msg);
        if(v.code == 0) then

            if v.data == nil then
                logError("[GetRooms] data is nil")
                --return
            else
                for k, v in pairs(v.data.channles) do
                    local index = string.find(k,"-")
                    if index then
                        local temp = string.split(k,"-")
                        if v  > 0 then
                            this.AddRoom(temp[1],v,tonumber(temp[2]))
                        end
                    end
                end
            end
        end
        this.AddEmptyRoom()
        table.sort(this.roomList[1],this.SortRoom)
        table.sort(this.roomList[2],this.SortRoom)
        if(funcBack~=nil)then
            funcBack();
        end
    end);
end
function LBSManager.AddEmptyRoom()
    local name = this.GetLocationName()
    if string.IsNilOrEmpty(name) then
        return
    end
    local num = #this.roomList[2]
    if num < 10 then
        for i = 1,10 do
            if not this.ContainsRoomCode(i,this.roomList[2]) then
                this.AddRoom(this.GetLocationName(),0,i)
            end
        end
    end
end
function LBSManager.ContainsRoomCode(code,rooms)
    for k,v in pairs(rooms) do
        if v.code == code then
            return true
        end
    end
    return false
end
---@private
function LBSManager.SortRoom(a,b)
    return a.code < b.code
end
---@private
function LBSManager.GetRoomChannel(roomName,code)
    return "world-room-"..AppConst.ServerId.."/"..roomName.."-"..code
end
---@private
function LBSManager.joinBroadcastChannel(room)
    if room == nil then return end
    this.curRoom =room;
    chatHandler.SetChannel(Config.MsgChannel.LBS,room.channel)
    local joinJson=this.getJoinData(room.channel);
    WebSocketMgr.GetInstance():Send(joinJson);
end
---@private
function LBSManager.QuitBroadcastChannel(room)
    if room == nil then return end
    this.preRoom = room
    local joinJson=this.getLeaveData(room.channel);
    WebSocketMgr.GetInstance():Send(joinJson);
end
function LBSManager.IsInRoom(channel)
    if this.curRoom == nil then return false end
    if this.curRoom.channel == channel then
        return true
    end
    return false
end
---@private
function LBSManager.getJoinData(channelId)
    joinData.action = "join"
    joinData.channel = channelId;
    joinData.orderId = orderId;
    orderId = orderId + 1;
    local json = getJsonStr(joinData);
    return string.gsub(json,"\\","")
end
---@private
function LBSManager.getLeaveData(channelId)
    joinData.action = "quit"
    joinData.channel = channelId;
    joinData.orderId = orderId;
    orderId = orderId + 1;
    local json = getJsonStr(joinData);
    return string.gsub(json,"\\","")
end
---@private
function LBSManager.broadCastCityMsg(channel,msg)
    cityMsg.action = "broadcast"
    cityMsg.channel = channel;
    cityMsg.message = msg;
    cityMsg.orderId = orderId;
    orderId = orderId + 1;
    local jsos=getJsonStr(cityMsg);
    local CityStrData=string.gsub(jsos,"\\","")
    WebSocketMgr.GetInstance():Send(CityStrData);
end
---@private
function LBSManager.JoinRoomSuc()
    if this.roomState == 2 then
        this.roomState = 0
        utimer.remove(this.timerId)
        this.timerId = nil
        this.JoinWorldFinished()
        FireEvent(Config.EventType.CityRoomJoinSuc)
    end
end
function LBSManager.QuitRoomSuc()
    if this.roomState == 1 then
        this.roomState = 2
        this.joinBroadcastChannel(this.curRoom)
    end
end
function LBSManager.StartLocation()
    if CompareOriginVersion("1.4.2.0001") then
        if LBSLocation.GetInstance() then
            LBSLocation.GetInstance():LocationDataGPS(nil)
        end
    end
end
function LBSManager.OnLocaltionOK()
    print("定位 OK")
    --定位--------------------------------------------------------------------------------------------------
    playerHandler.ReqChangeLbsMessage(logicMgr.LBSManager.GetLocationName())
end

return LBSManager